// ActionScript file
import mx.events.SliderEvent;
import mx.collections.ArrayCollection;
import model.*;
import mx.controls.List;
import mx.controls.Alert;
import components.*;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.events.Event;
import flash.events.MouseEvent;
import mx.utils.UIDUtil;
//skin embeded resource class declare	
[Embed("player_assets/play_h.jpg")]
public var _skin_play_over:Class;
[Embed("player_assets/play_d.jpg")]
public var _skin_play_down:Class;
[Embed("player_assets/play.jpg")]
public var _skin_play_up:Class;
[Embed("player_assets/play_n.jpg")]
public var _skin_play_disable:Class;
			
[Embed("player_assets/stop.jpg")]
public var _skin_pause_over:Class;
[Embed("player_assets/stop.jpg")]
public var _skin_pause_down:Class;
[Embed("player_assets/stop.jpg")]
public var _skin_pause_up:Class;
[Embed("player_assets/stop.jpg")]
public var _skin_pause_disable:Class;
				
			
private var userInfo:XML;

private var playList:PlayList;
private var player:PlayerModel;
private var _statusTimer:Timer;

//initializing code segement
private function _initEnviorment():void{
		var cmd:String = Application.application.parameters.command;
				
		if(cmd != null && cmd != ''){
				this._onCommand(cmd);
		}
		this._statusTimer = null;
}
private function _initUIComponent():void{
		this.player = new PlayerModel();
		this.player.addEventListener(PlayerEvent.MediaOpen,_playerEventHandler);
		this.player.addEventListener(PlayerEvent.Stop,_playerEventHandler);
		this.player.addEventListener(PlayerEvent.Pause,_playerEventHandler);
		this.player.addEventListener(PlayerEvent.VolumeChange,_playerEventHandler);
		this.player.addEventListener(PlayerEvent.MediaEnd,_playerEventHandler);
		this.player.addEventListener(PlayerEvent.PlayListsChange,_playerEventHandler);
				
		this.player.addEventListener(PlayerEvent.TimeTick,_timeTickEventHandler);
		this.player.addEventListener(PlayerEvent.Bufferring,_bufferringEventHandler);
				
		this.btn_play.addEventListener(MouseEvent.CLICK,this._play);
		this.btn_next.addEventListener(MouseEvent.CLICK,this._next);
		this.btn_prev.addEventListener(MouseEvent.CLICK,this._prev);
		
		this.cmb_playList.addEventListener(Event.CHANGE,this._onUserChangePlayList);
		
		this.slider_progress.addEventListener(SliderEvent.CHANGE,this._onUserChangePosition);
		this.slider_volume.addEventListener(SliderEvent.CHANGE,this._onUserChangeVolume);
				
				
		this.com_vote.addEventListener(VoteEvent.Vote,this._onUserVote);
}
private function init():void{
				
		this._initUIComponent();
		this._initEnviorment();
		
}

//player model event handler code segement
private function _timeTickEventHandler(evt:PlayerEvent):void{
		if(this.slider_progress.enabled == false){
				this.slider_progress.enabled = true;
				this.slider_progress.minimum = 0;
		}
		this.slider_progress.maximum = evt.playerTimeState.duration;
		this.lbl_timeStatus.text = evt.playerTimeState.currentPositionString+'/'+evt.playerTimeState.durationString;
		this.slider_progress.value = evt.playerTimeState.currentPosition;
}
private function _bufferringEventHandler(evt:ProgressEvent):void{		
		//this.lbl_timeStatus.text = '缓冲:'+(int(evt.bytesLoaded/evt.bytesTotal*100).toString())+'%';
		this.slider_progress.graphics.moveTo(0,4);
		this.slider_progress.graphics.lineTo(0,100);
}
private function _playerEventHandler(evt:PlayerEvent):void{
				
		switch(evt.type){
			case PlayerEvent.MediaOpen:	
			break;
			case PlayerEvent.Stop:
				this.slider_progress.enabled = false;
			break;
			case PlayerEvent.MediaEnd:
				if(evt.playerState.canNextSong){
					player.goNextSong();
				}
			break;
		}			
		_updateCtrl(evt.playerState);
		_updateVolumeCtrl(evt.playerState);
		_updateList(evt.playerState);
		_updateSongInfo(evt.playerState);
		_updatePlayList(evt.playerState);		
}

//update UI control status code segement
private function _updateCtrl(state:PlayerState):void{
		this.btn_play.enabled = (player.playLists.length>0)?true:false;
		this.btn_prev.enabled = state.canPrevSong?true:false;
		this.btn_next.enabled = state.canNextSong?true:false;
		if(state.engineState == PlayerState.PLAYING){
			this.btn_play.removeEventListener(MouseEvent.CLICK,this._play);
			this.btn_play.addEventListener(MouseEvent.CLICK,this._pause);
			this.btn_play.setStyle('upSkin',this._skin_pause_up);
			this.btn_play.setStyle('downSkin',this._skin_pause_down);
			this.btn_play.setStyle('overSkin',this._skin_pause_over);
			this.btn_play.setStyle('disabledSkin',this._skin_pause_disable);
		}else{
			this.btn_play.removeEventListener(MouseEvent.CLICK,this._pause);
			this.btn_play.addEventListener(MouseEvent.CLICK,this._play);
			this.btn_play.setStyle('upSkin',this._skin_play_up);
			this.btn_play.setStyle('downSkin',this._skin_play_down);
			this.btn_play.setStyle('overSkin',this._skin_play_over);
			this.btn_play.setStyle('disabledSkin',this._skin_play_disable);
		}
		
}
private function _updateVolumeCtrl(state:PlayerState):void{
		this.slider_volume.value = player.volume;
}
private function _updatePlayList(state:PlayerState):void{
		var curList:PlayList = state.currentPlayList;
		var lists:ArrayCollection = player.playLists as ArrayCollection;
		this.cmb_playList.dataProvider = lists;
		this.cmb_playList.labelField = 'listTitle';
		if(curList == null)
			return ;
		for(var i:int=0;i<lists.length;i++){
			var list:PlayList = lists[i];
			if(list.listID == curList.listID && list.listTitle == curList.listTitle){
				this.cmb_playList.selectedItem = list;
			}
		}
				
}
private function _updateSongInfo(state:PlayerState):void{
		var song:Song = state.currentSong;
		if(song == null)
			return;
		this.lbl_songName.text = 'Title：'+song.title;
		this.lbl_artist.text = 'Artist：'+song.author;
		this.lbl_pubDate.text = 'Publish：'+song.update.toString();
		this.img_cover.source = song.coverUrl;
		var voteCtrl:Vote = this.com_vote;
		song.ratings = 3;
		voteCtrl.enabled = true;
		voteCtrl.setRatings(song.ratings,1);
		
}
private function _updateList(state:PlayerState):void{
		var curList:PlayList = state.currentPlayList;
		var curSong:Song = state.currentSong;
		if(curList == null || curSong == null)
			return;
		this.list_song.dataProvider = curList.items;

				
		for(var i:int = 0;i<curList.items.length;i++){
			var s:Song = curList.items[i] as Song;
			if(s == curSong){
				this.list_song.selectedItem = s;
			}
			var listItem:PlayListItem = PlayListItem(this.list_song.itemToItemRenderer(s));
			if(listItem != null){
				listItem.addEventListener(PlayListItemEvent.ItemClick,this._onUserChangeSong);
				listItem.addEventListener(PlayListItemEvent.DelClick,this._onUserRemoveSong);
			}
		}
		//trace('list selected index:'+this.list_song.selectedIndex);
}

// event handlers for user intraction code segment

public function _onUserChangeSong(evt:PlayListItemEvent):void{
		var curList:PlayList = player.state.currentPlayList;
		var curSong:Song = player.state.currentSong;	
		var tarSong:Song = Song(evt.data);
		if(tarSong == curSong)
			return;
					
		for(var i:int = 0;i<curList.items.length;i++){
			var s:Song = curList.items[i] as Song;
			if(s == tarSong){
				player.goSongByIndex(i);
				break;
			}
		}
}
public function _onUserRemoveSong(evt:PlayListItemEvent):void{
		//trace('remove btn phase:'+evt.eventPhase);
		var tarSong:Song = Song(evt.data);
				
		//evt.stopPropagation();
		//trace(Button(evt.currentTarget).data);
		player.removeSong(tarSong);
}
private function _onUserChangePosition(evt:SliderEvent):void{
		var value:Number = evt.value;
		//trace(value);
		player.position = value;
}
private function _onUserChangeVolume(evt:SliderEvent):void{
		var value:Number = evt.value;
		//trace(value);
		player.volume = value;
}
private function _onUserChangePlayList(evt:Event):void{
		var list:PlayList = (evt.currentTarget as ComboBox).selectedItem as PlayList;
		//trace(list.listTitle);
		if(list == null)
			return;
		if(list.loaded == false){
			/* this play list doesn't been loaded */
		}else{
			player.playList(list.listID);		
		}
}
			
private function _onUserVote(evt:VoteEvent):void{
	/* implement code yourself*/
		
}

private function _play(evt:Event):void{
	player.play();
}
private function _pause(evt:Event):void{
	player.pause();
}
private function _next(evt:Event):void{
	player.goNextSong();
}
private function _prev(evt:Event):void{
	player.goPrevSong();
}

//response to remote controller command code segement
private function _onCommand(cmdMsg:String):void{
				
	var str:Array = cmdMsg.split('|');
	var cmd:String = str[0] as String;
	var args:String = str[1] as String;
	var url:String = '';
				
	switch(cmd){
		case 'PLAYLISTXML':		
			url = '/'+args;
			this._loadXML(url,_cmd_playListXML_cb);
			break;
		default:
			trace('unknown command'+cmd);
			break;
	}
}

private function _loadXML(url:String,callback:Function):void{
	this._message('Loading...',20);
	var myXML:XML = new XML();
	var XML_URL:String = url;
	var myXMLURL:URLRequest = new URLRequest(XML_URL);
	var myLoader:URLLoader = new URLLoader(myXMLURL);
	myLoader.dataFormat = URLLoaderDataFormat.TEXT;
	myLoader.addEventListener("complete", callback);				
}
private function _cmd_playListXML_cb(evt:Event):void{
	var loader:URLLoader = URLLoader(evt.target);
	var xml:XML = XML(loader.data);
	for each(var listXML:XML in xml.list){
		var list:PlayList = new PlayList();
		list.listID = UIDUtil.createUID();
		list.listTitle = listXML.listTitle;
		for each(var songXML:XML in listXML.songs.song){
			var song:Song = new Song();
			song.title = songXML.title;
			song.url = songXML.url;
			song.author = songXML.author;
			song.update = songXML.update;
			song.coverUrl = songXML.coverUrl;
			list.append(song);
		}
		player.appendPlayList(list);
	}
	this._messageHide(null);
}
			
// utility code segement
private function _message(msg:String,time:int):void{
	if(this._statusTimer != null){
		this._statusTimer.reset();
		this._statusTimer.delay = time*1000;
	}else{
		this._statusTimer = new Timer(time*1000);
		this._statusTimer.addEventListener(TimerEvent.TIMER,_messageHide);
	}
	this.lbl_status.text = msg;
	this.can_status.visible = true;
	this._statusTimer.start();
	
}			
private function _messageHide(evt:TimerEvent):void{
	this.lbl_status.text = '';
	this.can_status.visible = false;
	if(this._statusTimer != null)
		this._statusTimer.reset();
}
